import serial,time,yaml,paramiko,sys,os
from loggerconfig import config_logger
from pingparsing import PingParsing
from pingparsing import PingTransmitter
import pywifi,time

logger = config_logger("wifi stability test")

def do_ping(port):
    recv = []
    # 创建Ping发送对象，用于配置和发送ping请求
    transmitter = PingTransmitter()
    transmitter.destination = "fe80::ff:fe00:0"
    transmitter.count = 4
    transmitter.option_ipv6 = True # 启用 IPv6
    transmitter.interface = port # 接口名，%后面的数字

    # 创建Ping解析对象，用于解析ping结果
    ping_parsing = PingParsing()


    result = transmitter.ping()
    
    parsed_result = ping_parsing.parse(result.stdout)
    logger.info("返回信息 {}".format(parsed_result.as_dict()))
    time.sleep(1)


# def powercut_or_reboot_when_flashcp(powercutorreboot,_time,operatessh,ssh,operateserial):
#     print("子线程----断电或reboot")
#     if powercutorreboot == "power_cut":
#         print("等待{}重启".format("time"))
#         time.sleep(_time)
        
#         logger.info("------------------断电重启")
    
#         operatessh.disconnect_ssh(ssh)
        
#         ser = operateserial.connect_serial()
#         operateserial.send_data(ser,"\ncustom off 6000\n")
#         operateserial.disconnect_serial(ser)



#     elif powercutorreboot == "reboot":
#         print("等待{}重启".format(_time))
#         time.sleep(_time)
        
#         logger.info("------------------断电重启")
    
#         operatessh.sendcommand_ssh(ssh,"reboot")

#         operatessh.disconnect_ssh(ssh)
        
   
#     logger.info("-----powercut_or_reboot_when_flashcp----线程结束-------")








class OperateSerial:
    def __init__(self,port,baudrate):
        self.port =  port
        self.baudrate = baudrate


    def connect_serial(self):
        try:
            # 打开串口并配置参数
            ser = serial.Serial(
                port=self.port,
                baudrate=self.baudrate,
                bytesize=serial.EIGHTBITS,
                parity=serial.PARITY_NONE,
                stopbits=serial.STOPBITS_ONE
            )
            return ser
        except serial.SerialException as e:
            print("串口打开出错:", e)

    def disconnect_serial(self,ser):
        if ser and ser.is_open:
            ser.close()
            print("串口已关闭")

    def send_data(self,ser,cmd):
        # 配置串口参数
        if ser.is_open:
            print(f"串口已成功打开")

            command = cmd.encode('utf-8')

            if ser and ser.is_open :
                # if enter_flag:
                ser.write(command)
                print("已发送串口命令:", command.decode('utf-8'))
                time.sleep(1)  
                # enter_flag = False

            else:
                print("串口未打开，无法发送命令")
                time.sleep(1)

    def read_data(self,ser):
        try:
            while True:
                if ser and ser.is_open:
                    data = ser.readline()
                    if data:
                        decoded_data = data.decode('utf-8').strip()

                        if "ENTER YOUR COMMAND BELOW" in decoded_data:
                            print("子线程read_data 接收到 ENTER YOUR COMMAND BELOW , 设置 enter_flag = True")
                            enter_flag = True
                            time.sleep(1)
                            break
                    else:
                        time.sleep(0.1)
                else:
                    print("串口未打开，无法接收数据")
                    time.sleep(1)
        except Exception as e:
            print("读取数据线程出错:", e)

class OperateYaml:
    # def __init__(self,yaml_file):
    #     self.yaml_file = yaml_file
    
    def read_yaml(self,yaml_file):
        with open(yaml_file, 'r',encoding='utf - 8') as file:
            test_data = yaml.safe_load(file)['test_case']
        
        return test_data
    
class OperateSsh:
    def __init__(self,remote_ip,username,password):
        self.remote_ip = remote_ip
        self.username = username
        self.password = password

    def connect_ssh(self):
        # 创建SSH对象
        ssh = paramiko.SSHClient()
        # 允许连接不在know_hosts文件中的主机
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect(hostname=self.remote_ip, port=22, username=self.username, password=self.password)
            time.sleep(3)
            return ssh
        
        except:
            logger.info("连接异常")
            # 重新连接远程设备
            retry_count = 0
            max_retries = 6
            while retry_count < max_retries:
                try:
                    ssh.connect(hostname=self.remote_ip, port=22, username=self.username, password=self.password)
                    logger.info("重新连接成功")
                    return ssh
                    # break
                except (paramiko.AuthenticationException, paramiko.SSHException, OSError) as e:
                    logger.info(f"重新连接出错: {e}，正在进行第{retry_count + 1}次重试...")
                    retry_count += 1
                    time.sleep(6)
            if retry_count == max_retries:
                logger.info("达到最大重试次数，无法重新建立连接，请检查相关设置和网络情况。")
                ssh.close()
                return False

    def disconnect_ssh(self,ssh):
        ssh.close()

    def sendcommand_ssh(self,ssh,cmd):
        stdin, stdout, stderr = ssh.exec_command(cmd)
        result_cmd = stdout.read().decode('utf-8')

        logger.info("{} 返回： {}".format(cmd , result_cmd))
        return result_cmd
    
    def upload_file(self,local_path, remote_path, ssh):
        try:

            # 创建SFTP客户端对象，用于文件传输
            sftp = ssh.open_sftp()

            # 获取本地文件的文件名
            local_filename = os.path.basename(local_path)
            # 拼接远程设备上的完整目标路径（包含文件名）
            remote_full_path = os.path.join(remote_path, local_filename)
            # 上传文件
            sftp.put(local_path, remote_full_path)

            print(f"文件 {local_path} 已成功上传到远程设备 {remote_full_path}")

            # 关闭SFTP连接和SSH连接
            sftp.close()
            
        except paramiko.AuthenticationException as e:
            sftp.close()
            print(f"认证失败: {e}...退出")
            sys.exit()

        except paramiko.SSHException as e:
            sftp.close()
            print(f"SSH连接出错: {e}...退出")
            sys.exit()
            
        except FileNotFoundError as e:
            sftp.close()
            print(f"本地文件不存在: {e}...退出")
            sys.exit()

        except Exception as e:
            sftp.close()
            print(f"其他错误: {e}...退出")
            sys.exit()




def get_wifi_interfaces():
    wifi = pywifi.PyWiFi()  # 创建一个无限对象
    num = len(wifi.interfaces())
    if num <= 0:
        print("未找到无线网卡接口!\n")
        exit()
    if num == 1:
        wifi_iface = wifi.interfaces()[0]  # 取一个无限网卡
        print(u"无线网卡接口: %s\n" % (wifi_iface.name()))
        return wifi_iface
    else:
        print('%-4s   %s\n' % (u'序号', u'网卡接口名称'))
        for i, w in enumerate(wifi.interfaces()):
            print('%-4s   %s' % (i, w.name()))
        while True:
            iface_no = input('请选择网卡接口序号：')
            no = int(iface_no)
            if no >= 0 and no < num:
                return wifi.interfaces()[no]

# 扫描周围wifi
def scan_wifi(self):
    self.scan()   # 扫描
    time.sleep(3)
    wifi_info = self.scan_results()
    wifi_list = []
    for i in wifi_info:
        if i.signal > -100:  # 信号强度<-100的wifi几乎连不上
            wifi_list.append((i.ssid, i.signal, i.freq, i.bssid, i.akm))  # 添加到wifi列表

    return sorted(wifi_list, key=lambda x: x[1], reverse=True)  # 按信号强度由高到低排序


# 连接wifi
def connect_wifi(self,wifi_name):
    profile_info = pywifi.profile.Profile()  # 配置文件
    profile_info.ssid = wifi_name  # wifi名称
    profile_info.key = wifi_name  # wifi密码
    profile_info.auth = pywifi.const.AUTH_ALG_OPEN
    profile_info.akm.append(pywifi.const.AKM_TYPE_WPA2PSK)  # 加密类型
    profile_info.cipher = pywifi.const.CIPHER_TYPE_CCMP     # 加密单元

    self.remove_all_network_profiles()  # 删除其他配置文件
    print("删除其他配置文件")
    print("连接。。。。。")
    time.sleep(2)  # 删除其他配置文件
    tmp_profile = self.add_network_profile(profile_info)  # 加载配置文件

    self.connect(tmp_profile)  # 连接
    time.sleep(15)  # 尝试15秒能否成功连接


    if self.status() == pywifi.const.IFACE_CONNECTED:
        print("成功连接")
        return True
    else:
        print("失败")
        self.disconnect()  # 断开连接
        time.sleep(2)
        return False
    
def check_interface(self):
    if self.status() == pywifi.const.IFACE_CONNECTED:
        print("断开链接。。。")
        return True
    else:
        return False

